import type { NavigationGuardNext, RouteLocationNormalized, RouteRecordRaw } from "vue-router";
import NProgress from "@/utils/nprogress";
import { getAccessToken } from "@/utils/auth";
import router from "@/router";
import { usePermissionStore, useUserStore } from "@/store";
import { useNimStore } from "@/store/modules/nim";

const { getUserInfo } = useNimStore();
const { nimInfo } = storeToRefs(useNimStore());

/**
 * 初始化路由权限管理
 */
export function setupPermission() {
  const whiteList = ["/login"]; // 白名单路由（无需登录即可访问）
  router.beforeEach(async (to, from, next) => {
    NProgress.start(); // 开始加载进度条
    const isLogin = !!getAccessToken(); // 检查是否已登录

    if (isLogin) {
      await handleLoggedInUser(to, next);
    } else {
      handleLoggedOutUser(to, next, whiteList);
    }
  });

  router.afterEach(() => {
    NProgress.done(); // 路由跳转完成后关闭进度条
  });
}

/**
 * 处理已登录用户
 * @param to - 目标路由
 * @param next - 路由跳转函数
 */
async function handleLoggedInUser(to: RouteLocationNormalized, next: NavigationGuardNext) {
  const permissionStore = usePermissionStore();
  if (to.path === "/login") {
    next({ path: "/" });
    return;
  }

  if (permissionStore.isRoutesLoaded) {
    await handleRoutesLoaded(to, next);
  } else {
    await loadDynamicRoutes(to, next, permissionStore);
  }
}

/**
 * 处理动态路由已加载的情况
 * @param to - 目标路由
 * @param next - 路由跳转函数
 */
async function handleRoutesLoaded(to: RouteLocationNormalized, next: NavigationGuardNext) {
  if (to.matched.length === 0) {
    next("/404"); // 未匹配到路由时跳转到404页面
  } else {
    setDynamicTitle(to);
    next(); // 放行
  }
}

/**
 * 动态加载路由
 * @param to - 目标路由
 * @param next - 路由跳转函数
 * @param permissionStore - 权限管理状态
 */
async function loadDynamicRoutes(
  to: RouteLocationNormalized,
  next: NavigationGuardNext,
  permissionStore: ReturnType<typeof usePermissionStore>
) {
  try {
    const dynamicRoutes = await permissionStore.generateRoutes();
    dynamicRoutes.forEach((route: RouteRecordRaw) => {
      router.addRoute(route); // 动态添加路由
    });
    permissionStore.setFirstRoute(dynamicRoutes);
    if (to.path === "/") {
      const firstRoute = permissionStore.getFirstRoute();

      next({ path: firstRoute?.path });
    } else {
      next({ ...to, replace: true }); // 强制刷新路由匹配
    }
  } catch (error) {
    console.error("动态路由加载失败:", error);
    await useUserStore().clearUserData(); // 清空用户数据
    redirectToLogin(to, next); // 重定向到登录页
  } finally {
    NProgress.done(); // 结束加载进度条
  }
}

/**
 * 设置动态页面标题
 * @param to - 目标路由
 */
function setDynamicTitle(to: RouteLocationNormalized) {
  const title = (to.params.title as string) || (to.query.title as string);
  if (title) to.meta.title = title;
}

/**
 * 处理未登录用户
 * @param to - 目标路由
 * @param next - 路由跳转函数
 * @param whiteList - 白名单路由
 */
function handleLoggedOutUser(
  to: RouteLocationNormalized,
  next: NavigationGuardNext,
  whiteList: string[]
) {
  if (whiteList.includes(to.path)) {
    next(); // 白名单路由直接放行
  } else {
    redirectToLogin(to, next); // 未登录用户重定向到登录页
  }
}

/**
 * 重定向到登录页
 * @param to - 目标路由
 * @param next - 路由跳转函数
 */
function redirectToLogin(to: RouteLocationNormalized, next: NavigationGuardNext) {
  const redirect = encodeURIComponent(to.fullPath);
  next(`/login?redirect=${redirect}`); // 保留原始路径作为redirect参数
}

/** 判断是否有权限 */
export function hasAuth(value: string | string[], type: "button" | "role" = "button") {
  const { roles, perms } = useUserStore().userInfo;

  // 超级管理员 拥有所有权限
  if (type === "button" && roles.includes("ROOT")) {
    return true;
  }

  const auths = type === "button" ? perms : roles;
  return typeof value === "string"
    ? auths.includes(value)
    : value.some((perm) => auths.includes(perm));
}
